class Item < ActiveRecord::Base  
  belongs_to            :order
  belongs_to            :photo
  belongs_to            :video
  belongs_to            :user
  belongs_to            :photo_size
  belongs_to            :gallery
  belongs_to            :price_list
  has_many              :itemizations
  has_many              :item_options, :through => :itemizations
  
  validates_presence_of :user
  validates_presence_of :order
  validates_presence_of :price_list, :if => :item_is_for_photo?
  validate              :must_contain_either_a_photo_or_a_video
  validate              :must_contain_only_either_a_photo_or_a_video
  
  before_validation     :assign_item_to_order
  before_save           :ensure_price_list_equality_and_assign_default_values
  before_save           :ensure_item_is_purchasable
  after_save            :create_itemizations
  after_save            :assign_default_video_option
  after_save            :ensure_item_option_price_list_equality
  after_destroy         :destroy_dependents
  
  def available_item_options
    self.item_is_for_photo? ? ItemOption.find(:all, :conditions => ['for_photo = ?', true]).reject {|item_option| item_option.price_list != self.price_list} : ItemOption.find(:all, :conditions => ['for_video = ?', true])
  end
  
  def item_is_for_photo?
    self.photo ? true : false
  end
  
  def must_contain_either_a_photo_or_a_video
    self.errors.add("Order item must contain either a photo or a video") unless self.photo or self.video
  end
  
  def must_contain_only_either_a_photo_or_a_video
    self.errors.add("Order item must contain only either a photo or a video") if self.photo and self.video
  end
  
  def cost
    self.photo_size.cost if self.photo
  end
  
  def options_cost
    self.item_options.collect {|item_option| item_option.cost}.sum
  end
  
  def item_options_ids=(item_options_ids = [])
    @item_options_ids = item_options_ids
  end
  
  def description
    unless self.item_options.empty?
      item_options_names = ""
      if self.item_options.length > 1
        self.item_options.each {|item_option| (item_option == self.item_options.last) ? (item_options_names.chomp!(", ") << (" and " + item_option.name)) : (item_options_names << (item_option.name + ", "))}
      elsif self.item_options.length == 1
        item_options_names << self.item_options.first.name
      end
    end
    description = ""
    if self.photo
      description << ("[" + self.photo_size.size + "] Photo ")
      (description << ("with the " + item_options_names + " option(s) for ")) if item_options_names
      self.photo.caption ? (description << ("\"" + self.photo.caption + "\"")) : (description << self.photo.filename)
    elsif self.video
      (description << (item_options_names + " of ")) unless item_options_names.nil?
      self.video.title ? (description << ("\"" + self.video.title + "\"")) : (description << self.video.filename)
    end
    description
  end
  
protected
  def ensure_item_option_price_list_equality
    (self.reload.item_options.each {|item_option| (self.itemizations.each {|itemization| itemization.destroy}) unless (item_option.price_list == self.price_list)}) if self.photo
  end
  def ensure_price_list_equality_and_assign_default_values
    # this might need some rethinking...
    (self.photo_size = self.price_list.photo_sizes.first) unless self.photo_size
    ((self.photo_size = self.price_list.photo_sizes.first) unless (self.photo_size.price_list == self.price_list)) if self.photo
    (self.quantity = 1) unless self.quantity
  end
  def assign_default_video_option
    Itemization.create!(:item_id => self.id, :item_option_id => ItemOption.find(:all, :order => "cost asc", :conditions => ['for_video = ?', true]).first.id) if (self.itemizations.empty? && self.video)
  end
  def assign_item_to_order    
    @order = Order.find(:all, :conditions => ["user_id = #{self.user.id} AND is_completed = ?", false]).first
    @order = Order.create!(:user => self.user, :is_completed => false) if @order.nil?
    self.set_order_target(@order)
    self.order = @order
  end
  def create_itemizations
    self.itemizations.each {|itemization| itemization.destroy if @item_options_ids} unless self.itemizations.empty?
    @item_options_ids.each {|item_option_id| Itemization.create!(:item_id => self.id, :item_option_id => item_option_id)} unless @item_options_ids.nil?
  end
  def destroy_dependents
    self.itemizations.each {|itemization| itemization.destroy} unless self.itemizations.empty?
  end
  def ensure_item_is_purchasable
    self.photo ? (self.errors.add(:photo, "This photo can not be added to the cart because it's not purchasable") if self.photo.non_purchasable?) : (self.errors.add(:video, "This video can not be added to the cart because it's not purchasable") unless self.video.non_purchasable?)
  end
end
